<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Java基础3-线程的状态有哪些 | Hexo</title>
  <meta name="keywords" content="">
  <meta name="description" content="Java基础3-线程的状态有哪些 | Hexo">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="description" content="Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick">
<meta property="og:type" content="article">
<meta property="og:title" content="Hello World">
<meta property="og:url" content="http://yoursite.com/2020/07/27/hello-world/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2020-07-27T05:17:47.002Z">
<meta property="article:modified_time" content="2020-07-27T05:17:47.002Z">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">


<link rel="icon" href="/img/avatar.jpg">

<link href="/css/style.css?v=1.1.0" rel="stylesheet">

<link href="/css/hl_theme/atom-light.css?v=1.1.0" rel="stylesheet">

<link href="//cdn.jsdelivr.net/npm/animate.css@4.1.0/animate.min.css" rel="stylesheet">

<script src="//cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
<script src="/js/titleTip.js?v=1.1.0" ></script>

<script src="//cdn.jsdelivr.net/npm/highlightjs@9.16.2/highlight.pack.min.js"></script>
<script>
    hljs.initHighlightingOnLoad();
</script>

<script src="//cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js"></script>



<script src="//cdn.jsdelivr.net/npm/jquery.cookie@1.4.1/jquery.cookie.min.js" ></script>

<script src="/js/iconfont.js?v=1.1.0" ></script>

<meta name="generator" content="Hexo 4.2.1"></head>
<div style="display: none">
  <input class="theme_disqus_on" value="false">
  <input class="theme_preload_comment" value="">
  <input class="theme_blog_path" value="">
  <input id="theme_shortcut" value="true" />
</div>


<body>
<aside class="nav">
    <div class="nav-left">
        <a href="/" class="avatar_target">
    <img class="avatar" src="/img/avatar.jpg" />
</a>
<div class="author">
    <span>John Doe</span>
</div>

<div class="icon">
    
        
        <a title="rss" href="/atom.xml" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-rss"></use>
                </svg>
            
        </a>
        
    
        
        <a title="github" href="https://github.com/yelog" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-github"></use>
                </svg>
            
        </a>
        
    
        
        <a title="facebook" href="https://www.facebook.com/faker.tops" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-facebook"></use>
                </svg>
            
        </a>
        
    
        
    
        
    
        
        <a title="instagram" href="https://www.facebook.com/faker.tops" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-instagram"></use>
                </svg>
            
        </a>
        
    
        
        <a title="reddit" href="https://www.reddit.com/user/yelog/" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-reddit"></use>
                </svg>
            
        </a>
        
    
        
        <a title="weibo" href="http://weibo.com/u/2307534817" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-weibo"></use>
                </svg>
            
        </a>
        
    
        
        <a title="jianshu" href="https://www.jianshu.com/u/ff56736de7cf" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-jianshu"></use>
                </svg>
            
        </a>
        
    
        
        <a title="zhihu" href="https://www.zhihu.com/people/jaytp/activities" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-zhihu"></use>
                </svg>
            
        </a>
        
    
        
    
        
        <a title="oschina" href="https://my.oschina.net/yelog" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-oschina"></use>
                </svg>
            
        </a>
        
    
        
    
        
        <a title="email" href="mailto:jaytp@qq.com" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-email"></use>
                </svg>
            
        </a>
        
    
        
        <a title="qq" href="http://wpa.qq.com/msgrd?v=3&uin=872336115&site=qq&menu=yes" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-qq"></use>
                </svg>
            
        </a>
        
    
        
        <a title="kugou" href="https://www.kugou.com/" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-kugou"></use>
                </svg>
            
        </a>
        
    
        
        <a title="neteasemusic" href="https://music.163.com/#/user/home?id=88151013" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-neteasemusic"></use>
                </svg>
            
        </a>
        
    
</div>




<ul>
    <li><div class="all active" data-rel="All">All<small>(10)</small></div></li>
    
        
            
            <li><div data-rel="后端">后端<small>(3)</small></div>
                
            </li>
            
        
    
        
            
            <li><div data-rel="Java基础">Java基础<small>(4)</small></div>
                
            </li>
            
        
    
</ul>
<div class="left-bottom">
    <div class="menus">
    
    
    
    
    </div>
    <div><a class="about  hasFriend  site_url"  href="/about">About</a><a style="width: 50%"  class="friends">Friends</a></div>
</div>
<input type="hidden" id="yelog_site_posts_number" value="10">

<div style="display: none">
    <span id="busuanzi_value_site_uv"></span>
    <span id="busuanzi_value_site_pv"></span>
</div>

    </div>
    <div class="nav-right">
        <div class="friends-area">
    <div class="friends-title">
        Links
        <i class="iconfont icon-left"></i>
    </div>
    <div class="friends-content">
        <ul>
            
            <li><a target="_blank" href="http://yelog.org/">叶落阁</a></li>
            
        </ul>
    </div>
</div>
        <div class="title-list">
    <div class="right-top">
        <div id="default-panel">
            <i class="iconfont icon-search" data-title="搜索 快捷键 i"></i>
            <div class="right-title">All</div>
            <i class="iconfont icon-file-tree" data-title="切换到大纲视图 快捷键 w"></i>
        </div>
        <div id="search-panel">
            <i class="iconfont icon-left" data-title="返回"></i>
            <input id="local-search-input" />
            <label class="border-line" for="input"></label>
            <i class="iconfont icon-case-sensitive" data-title="大小写敏感"></i>
            <i class="iconfont icon-tag" data-title="标签"></i>
        </div>
        <div id="outline-panel" style="display: none">
            <div class="right-title">大纲</div>
            <i class="iconfont icon-list" data-title="切换到文章列表"></i>
        </div>
    </div>

    <div class="tags-list">
    <input id="tag-search" />
    <div class="tag-wrapper">
        
            <li class="article-tag-list-item">
                <i class="iconfont icon-tag"></i><a>Git</a>
            </li>
        
    </div>

</div>

    
    <nav id="title-list-nav">
        
        <a  class="All "
           href="/2020/07/27/%E5%BE%AE%E6%9C%8D%E5%8A%A1%E9%98%B6%E6%AE%B5/"
           data-tag=""
           data-author="" >
            <span class="post-title" title="微服务阶段">微服务阶段</span>
            <span class="post-date" title="2020-07-27 14:31:06">2020/07/27</span>
        </a>
        
        <a  class="All "
           href="/2020/07/27/hello-world/"
           data-tag=""
           data-author="" >
            <span class="post-title" title="Hello World">Hello World</span>
            <span class="post-date" title="2020-07-27 13:17:47">2020/07/27</span>
        </a>
        
        <a  class="All "
           href="/2020/07/23/Java%E5%9F%BA%E7%A1%805/"
           data-tag=""
           data-author="" >
            <span class="post-title" title="Java基础5-">Java基础5-</span>
            <span class="post-date" title="2020-07-23 23:51:18">2020/07/23</span>
        </a>
        
        <a  class="All Java基础 "
           href="/2020/07/21/Java%E5%9F%BA%E7%A1%804-%E8%AF%A6%E8%A7%A3-ThreadPoolExecutor-%E7%9A%84%E5%8F%82%E6%95%B0%E5%90%AB%E4%B9%89%E5%8F%8A%E6%BA%90%E7%A0%81%E6%89%A7%E8%A1%8C%E6%B5%81%E7%A8%8B/"
           data-tag=""
           data-author="" >
            <span class="post-title" title="java基础4-详解 ThreadPoolExecutor 的参数含义及源码执行流程">java基础4-详解 ThreadPoolExecutor 的参数含义及源码执行流程</span>
            <span class="post-date" title="2020-07-21 21:53:39">2020/07/21</span>
        </a>
        
        <a  class="All Java基础 "
           href="/2020/07/20/Java%E5%9F%BA%E7%A1%803-%E7%BA%BF%E7%A8%8B%E7%9A%84%E7%8A%B6%E6%80%81%E6%9C%89%E5%93%AA%E4%BA%9B/"
           data-tag=""
           data-author="" >
            <span class="post-title" title="Java基础3-线程的状态有哪些">Java基础3-线程的状态有哪些</span>
            <span class="post-date" title="2020-07-20 10:21:12">2020/07/20</span>
        </a>
        
        <a  class="All Java基础 "
           href="/2020/07/17/Java%E5%9F%BA%E7%A1%802-HashMap%E5%BA%95%E5%B1%82%E5%8E%9F%E7%90%86/"
           data-tag=""
           data-author="" >
            <span class="post-title" title="Java基础2-HashMap底层原理">Java基础2-HashMap底层原理</span>
            <span class="post-date" title="2020-07-17 13:02:46">2020/07/17</span>
        </a>
        
        <a  class="All Java基础 "
           href="/2020/07/13/Java%E5%9F%BA%E7%A1%801-Spring%E7%89%B9%E7%82%B9%E6%98%AF%E4%BB%80%E4%B9%88/"
           data-tag=""
           data-author="" >
            <span class="post-title" title="Java基础1-Spring特点是什么">Java基础1-Spring特点是什么</span>
            <span class="post-date" title="2020-07-13 17:24:53">2020/07/13</span>
        </a>
        
        <a  class="All 后端 "
           href="/2020/07/09/%E4%BD%BF%E7%94%A8SSH%E5%AF%86%E9%92%A5%E8%BF%9E%E6%8E%A5Github/"
           data-tag=""
           data-author="" >
            <span class="post-title" title="使用SSH密钥连接Github">使用SSH密钥连接Github</span>
            <span class="post-date" title="2020-07-09 18:13:36">2020/07/09</span>
        </a>
        
        <a  class="All 后端 "
           href="/2020/07/09/%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E4%BB%8E0%E5%BC%80%E5%A7%8B%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2/"
           data-tag=""
           data-author="" >
            <span class="post-title" title="手把手教你从0开始搭建个人博客">手把手教你从0开始搭建个人博客</span>
            <span class="post-date" title="2020-07-09 17:27:06">2020/07/09</span>
        </a>
        
        <a  class="All 后端 "
           href="/2020/07/08/Git%E5%AE%89%E8%A3%85/"
           data-tag="Git"
           data-author="" >
            <span class="post-title" title="Git安装">Git安装</span>
            <span class="post-date" title="2020-07-08 13:04:43">2020/07/08</span>
        </a>
        
        <div id="no-item-tips">

        </div>
    </nav>
    <div id="outline-list">
    </div>
</div>
    </div>
    <div class="hide-list">
        <div class="semicircle" data-title="切换全屏 快捷键 s">
            <div class="brackets first"><</div>
            <div class="brackets">&gt;</div>
        </div>
    </div>
</aside>
<div id="post">
    <div class="pjax">
        <article id="post-Java基础3-线程的状态有哪些" class="article article-type-post" itemscope itemprop="blogPost">
    
        <h1 class="article-title">Java基础3-线程的状态有哪些</h1>
    
    <div class="article-meta">
        
        
        
        <span class="book">
            <i class="iconfont icon-category"></i>
            
            <a  data-rel="Java基础">Java基础</a>
            
        </span>
        
        
    </div>
    <div class="article-meta">
        
            Created At : <time class="date" title='Updated At: 2020-07-21 21:39:58'>2020-07-20 10:21</time>
        
    </div>
    <div class="article-meta">
        
        
        <span id="busuanzi_container_page_pv">
            Views 👀 :<span id="busuanzi_value_page_pv">
                <span class="count-comment">
                    <span class="spinner">
                      <div class="cube1"></div>
                      <div class="cube2"></div>
                    </span>
                </span>
            </span>
        </span>
        
        
    </div>
    
    <div class="toc-ref">
    
        <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#一、什么是线程"><span class="toc-text">一、什么是线程</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#二、它是如何工作的"><span class="toc-text">二、它是如何工作的</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-BLOCKED-和-WAITING-的区别"><span class="toc-text">1.BLOCKED 和 WAITING 的区别</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-start-和-run-的区别"><span class="toc-text">2.start() 和 run() 的区别</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-线程优先级"><span class="toc-text">3.线程优先级</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-线程的常用方法"><span class="toc-text">4.线程的常用方法</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#（1）join"><span class="toc-text">（1）join()</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#（2）yield"><span class="toc-text">（2）yield()</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#小结"><span class="toc-text">小结</span></a></li></ol>
    
<style>
    .left-col .switch-btn,
    .left-col .switch-area {
        display: none;
    }
    .toc-level-3 i,
    .toc-level-3 ol {
        display: none !important;
    }
</style>
</div>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="一、什么是线程"><a href="#一、什么是线程" class="headerlink" title="一、什么是线程"></a>一、什么是线程</h1><ul>
<li><p>线程（Thread）是并发编程的基础，也是程序执行的最小单元，它依托进程而存在。一个进程中可以包含多个线程，多线程可以共享一块内存空间和一组系统资源，因此线程之间的切换更加节省资源、更加轻量化，也因此被称为轻量级的进程。</p>
</li>
<li><p>当然，线程也是面试中常被问到的一个知识点，是程序员必备的基础技能，使用它可以有效地提高程序的整体运行速度。</p>
</li>
</ul>
<hr>
<p><strong>本文章的面试问题是，线程的状态有哪些？它是如何工作的？</strong></p>
<p><strong>典型回答</strong></p>
<blockquote>
<p>线程的状态在 JDK 1.5 之后以枚举的方式被定义在 Thread 的源码中，它总共包含以下 6 个状态：</p>
</blockquote>
<ul>
<li>NEW，新建状态，线程被创建出来，但尚未启动时的线程状态；</li>
<li>RUNNABLE，就绪状态，表示可以运行的线程状态，它可能正在运行，或者是在排队等待操作系统给它分配 CPU 资源；</li>
<li>BLOCKED，阻塞等待锁的线程状态，表示处于阻塞状态的线程正在等待监视器锁，比如等待执行 synchronized 代码块或者使用 synchronized 标记的方法；</li>
<li>WAITING，等待状态，一个处于等待状态的线程正在等待另一个线程执行某个特定的动作，比如，一个线程调用了 Object.wait() 方法，那它就在等待另一个线程调用 Object.notify() 或 Object.notifyAll() 方法；</li>
<li>TIMED_WAITING，计时等待状态，和等待状态（WAITING）类似，它只是多了超时时间，比如调用了有超时时间设置的方法 Object.wait(long timeout) 和 Thread.join(long timeout) 等这些方法时，它才会进入此状态；</li>
<li>TERMINATED，终止状态，表示线程已经执行完成。</li>
</ul>
<hr>
<h1 id="二、它是如何工作的"><a href="#二、它是如何工作的" class="headerlink" title="二、它是如何工作的"></a>二、它是如何工作的</h1><p>线程状态的源代码如下：</p>
<pre class="brush:java">
public enum State {
    /**
     * 新建状态，线程被创建出来，但尚未启动时的线程状态
     */
    NEW,

    /**
     * 就绪状态，表示可以运行的线程状态，但它在排队等待来自操作系统的 CPU 资源
     */
    RUNNABLE,

    /**
     * 阻塞等待锁的线程状态，表示正在处于阻塞状态的线程
     * 正在等待监视器锁，比如等待执行 synchronized 代码块或者
     * 使用 synchronized 标记的方法
     */
    BLOCKED,

    /**
     * 等待状态，一个处于等待状态的线程正在等待另一个线程执行某个特定的动作。
     * 例如，一个线程调用了 Object.wait() 它在等待另一个线程调用
     * Object.notify() 或 Object.notifyAll()
     */
    WAITING,

    /**
     * 计时等待状态，和等待状态 (WAITING) 类似，只是多了超时时间，比如
     * 调用了有超时时间设置的方法 Object.wait(long timeout) 和 
     * Thread.join(long timeout) 就会进入此状态
     */
    TIMED_WAITING,

    /**
     * 终止状态，表示线程已经执行完成
     */
}
</pre>

<blockquote>
<p>线程的工作模式是，首先先要创建线程并指定线程需要执行的业务方法，然后再调用线程的 start() 方法，此时线程就从 NEW（新建）状态变成了 RUNNABLE（就绪）状态，此时线程会判断要执行的方法中有没有 synchronized 同步代码块，如果有并且其他线程也在使用此锁，那么线程就会变为 BLOCKED（阻塞等待）状态，当其他线程使用完此锁之后，线程会继续执行剩余的方法。</p>
</blockquote>
<blockquote>
<p>当遇到 Object.wait() 或 Thread.join() 方法时，线程会变为 WAITING（等待状态）状态，如果是带了超时时间的等待方法，那么线程会进入 TIMED_WAITING（计时等待）状态，当有其他线程执行了 notify() 或 notifyAll() 方法之后，线程被唤醒继续执行剩余的业务方法，直到方法执行完成为止，此时整个线程的流程就执行完了，执行流程如下图所示：</p>
</blockquote>
<p><img src="https://s1.ax1x.com/2020/07/20/UhPO0J.png" alt=""></p>
<hr>
<p><strong>考点分析</strong></p>
<blockquote>
<p>线程一般会作为并发编程的起始问题，用于引出更多的关于并发编程的面试问题。当然对于线程的掌握程度也决定了你对并发编程的掌握程度，通常面试官还会问：</p>
</blockquote>
<ul>
<li>BLOCKED（阻塞等待）和 WAITING（等待）有什么区别？</li>
<li>start() 方法和 run() 方法有什么区别？</li>
<li>线程的优先级有什么用？该如何设置？</li>
<li>线程的常用方法有哪些？</li>
</ul>
<p>接下来我们一起来看这些问题的答案。</p>
<hr>
<p><strong>知识扩展</strong></p>
<hr>
<h2 id="1-BLOCKED-和-WAITING-的区别"><a href="#1-BLOCKED-和-WAITING-的区别" class="headerlink" title="1.BLOCKED 和 WAITING 的区别"></a><strong>1.BLOCKED 和 WAITING 的区别</strong></h2><blockquote>
<p>虽然 BLOCKED 和 WAITING 都有等待的含义，但二者有着本质的区别，首先它们状态形成的调用方法不同，其次 BLOCKED 可以理解为当前线程还处于活跃状态，只是在阻塞等待其他线程使用完某个锁资源；而 WAITING 则是因为自身调用了 Object.wait() 或着是 Thread.join() 又或者是 LockSupport.park() 而进入等待状态，只能等待其他线程执行某个特定的动作才能被继续唤醒，比如当线程因为调用了 Object.wait() 而进入 WAITING 状态之后，则需要等待另一个线程执行 Object.notify() 或 Object.notifyAll() 才能被唤醒。</p>
</blockquote>
<hr>
<h2 id="2-start-和-run-的区别"><a href="#2-start-和-run-的区别" class="headerlink" title="2.start() 和 run() 的区别"></a><strong>2.start() 和 run() 的区别</strong></h2><hr>
<blockquote>
<p>首先从 Thread 源码来看，start() 方法属于 Thread 自身的方法，并且使用了 synchronized 来保证线程安全，源码如下：</p>
</blockquote>
<pre class="brush:java">
public synchronized void start() {
    // 状态验证，不等于 NEW 的状态会抛出异常
    if (threadStatus != 0)
        throw new IllegalThreadStateException();
    // 通知线程组，此线程即将启动

    group.add(this);
    boolean started = false;
    try {
        start0();
        started = true;
    } finally {
        try {
            if (!started) {
                group.threadStartFailed(this);
            }
        } catch (Throwable ignore) {
            // 不处理任何异常，如果 start0 抛出异常，则它将被传递到调用堆栈上
        }
    }
}
</pre>

<blockquote>
<p>run() 方法为 Runnable 的抽象方法，必须由调用类重写此方法，重写的 run() 方法其实就是此线程要执行的业务方法，源码如下：</p>
</blockquote>
<pre class="brush:java">
public class Thread implements Runnable {
 // 忽略其他方法......
  private Runnable target;
  @Override
  public void run() {
      if (target != null) {
          target.run();
      }
  }
}
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}
</pre>

<blockquote>
<p>从执行的效果来说，start() 方法可以开启多线程，让线程从 NEW 状态转换成 RUNNABLE 状态，而 run() 方法只是一个普通的方法。</p>
</blockquote>
<blockquote>
<p>其次，它们可调用的次数不同，start() 方法不能被多次调用，否则会抛出 java.lang.IllegalStateException；而 run() 方法可以进行多次调用，因为它只是一个普通的方法而已。</p>
</blockquote>
<hr>
<h2 id="3-线程优先级"><a href="#3-线程优先级" class="headerlink" title="3.线程优先级"></a><strong>3.线程优先级</strong></h2><hr>
<blockquote>
<p>在 Thread 源码中和线程优先级相关的属性有 3 个：</p>
</blockquote>
<pre class="brush:java">
// 线程可以拥有的最小优先级
public final static int MIN_PRIORITY = 1;

// 线程默认优先级
public final static int NORM_PRIORITY = 5;

// 线程可以拥有的最大优先级
public final static int MAX_PRIORITY = 10
</pre>

<blockquote>
<p>线程的优先级可以理解为线程抢占 CPU 时间片的概率，优先级越高的线程优先执行的概率就越大，但并不能保证优先级高的线程一定先执行。</p>
</blockquote>
<blockquote>
<p>在程序中我们可以通过 Thread.setPriority() 来设置优先级，setPriority() 源码如下：</p>
</blockquote>
<pre class="brush:java">
public final void setPriority(int newPriority) {
    ThreadGroup g;
    checkAccess();
    // 先验证优先级的合理性
    if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
        throw new IllegalArgumentException();
    }
    if((g = getThreadGroup()) != null) {
        // 优先级如果超过线程组的最高优先级，则把优先级设置为线程组的最高优先级
        if (newPriority > g.getMaxPriority()) {
            newPriority = g.getMaxPriority();
        }
        setPriority0(priority = newPriority);
    }
}
</pre>

<hr>
<h2 id="4-线程的常用方法"><a href="#4-线程的常用方法" class="headerlink" title="4.线程的常用方法"></a><strong>4.线程的常用方法</strong></h2><hr>
<blockquote>
<p>线程的常用方法有以下几个。</p>
</blockquote>
<h3 id="（1）join"><a href="#（1）join" class="headerlink" title="（1）join()"></a><strong>（1）join()</strong></h3><blockquote>
<p>在一个线程中调用 other.join() ，这时候当前线程会让出执行权给 other 线程，直到 other 线程执行完或者过了超时时间之后再继续执行当前线程，join() 源码如下：</p>
</blockquote>
<pre class="brush:java">
public final synchronized void join(long millis)
throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0;
    // 超时时间不能小于 0
    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }
    // 等于 0 表示无限等待，直到线程执行完为之
    if (millis == 0) {
        // 判断子线程 (其他线程) 为活跃线程，则一直等待
        while (isAlive()) {
            wait(0);
        }
    } else {
        // 循环判断
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            wait(delay);
            now = System.currentTimeMillis() - base;
        }
    }
}
</pre>

<blockquote>
<p>从源码中可以看出 join() 方法底层还是通过 wait() 方法来实现的。</p>
</blockquote>
<p>例如，在未使用 join() 时，代码如下：</p>
<pre class="brush:java">
public class ThreadExample {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            for (int i = 1; i < 6; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("子线程睡眠：" + i + "秒。");
            }
        });
        thread.start(); // 开启线程
        // 主线程执行
        for (int i = 1; i < 4; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("主线程睡眠：" + i + "秒。");
        }
    }
}
</pre>

<p>程序执行结果为：</p>
<pre class="brush:java">
主线程睡眠：1秒。
子线程睡眠：1秒。
主线程睡眠：2秒。
子线程睡眠：2秒。
主线程睡眠：3秒。
子线程睡眠：3秒。
子线程睡眠：4秒。
子线程睡眠：5秒。
</pre>

<p>从结果可以看出，在未使用 join() 时主子线程会交替执行。</p>
<p>然后我们再把 join() 方法加入到代码中，代码如下：</p>
<pre class="brush:java">
public class ThreadExample {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            for (int i = 1; i < 6; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("子线程睡眠：" + i + "秒。");
            }
        });
        thread.start(); // 开启线程
        thread.join(2000); // 等待子线程先执行 2 秒钟
        // 主线程执行
        for (int i = 1; i < 4; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("主线程睡眠：" + i + "秒。");
        }
    }
}
</pre>

<p>程序执行结果为：</p>
<pre class="brush:java">
子线程睡眠：1秒。
子线程睡眠：2秒。
主线程睡眠：1秒。 
// thread.join(2000); 等待 2 秒之后，主线程和子线程再交替执行
子线程睡眠：3秒。
主线程睡眠：2秒。
子线程睡眠：4秒。
子线程睡眠：5秒。
主线程睡眠：3秒。
从执行结果可以看出，添加 join() 方法之后，主线程会先等子线程执行 2 秒之后才继续执行。
</pre>

<hr>
<h3 id="（2）yield"><a href="#（2）yield" class="headerlink" title="（2）yield()"></a><strong>（2）yield()</strong></h3><p>看 Thread 的源码可以知道 yield() 为本地方法，也就是说 yield() 是由 C 或 C++ 实现的，源码如下：</p>
<pre class="brush:java">
public static native void yield();
</pre>

<blockquote>
<p>yield() 方法表示给线程调度器一个当前线程愿意出让 CPU 使用权的暗示，但是线程调度器可能会忽略这个暗示。</p>
</blockquote>
<p>比如我们执行这段包含了 yield() 方法的代码，如下所示：</p>
<pre class="brush:java">
public static void main(String[] args) throws InterruptedException {
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("线程：" +
                        Thread.currentThread().getName() + " I：" + i);
                if (i == 5) {
                    Thread.yield();
                }
            }
        }
    };
    Thread t1 = new Thread(runnable, "T1");
    Thread t2 = new Thread(runnable, "T2");
    t1.start();
    t2.start();
}
</pre>

<blockquote>
<p>当我们把这段代码执行多次之后会发现，每次执行的结果都不相同，这是因为 yield() 执行非常不稳定，线程调度器不一定会采纳 yield() 出让 CPU 使用权的建议，从而导致了这样的结果。</p>
</blockquote>
<hr>
<h1 id="小结"><a href="#小结" class="headerlink" title="小结"></a><strong>小结</strong></h1><hr>
<blockquote>
<p>本文章我们介绍了线程的 6 种状态以及线程的执行流程，还介绍了 BLOCKED（阻塞等待）和 WAITING（等待）的区别，start() 方法和 run() 方法的区别，以及 join() 方法和 yield() 方法的作用，但我们不能死记硬背，要多动手实践才能真正的理解这些知识点。</p>
</blockquote>

      
       <hr><span style="font-style: italic;color: gray;"> 转载请注明来源，欢迎对文章中的引用来源进行考证，欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论，也可以邮件至 jaytp@qq.com </span>
    </div>
</article>


<p>
    <a  class="dashang" onclick="dashangToggle()">💰</a>
</p>






    




    </div>
    <div class="copyright">
        <p class="footer-entry">
    ©2016-2020 Yelog
</p>
<p class="footer-entry">Built with <a href="https://hexo.io/" target="_blank">Hexo</a> and <a href="https://github.com/yelog/hexo-theme-3-hexo" target="_blank">3-hexo</a> theme</p>

    </div>
    <div class="full-toc">
        <button class="full" data-title="切换全屏 快捷键 s"><span class="min "></span></button>
<a class="" id="rocket" ></a>

    </div>
</div>

<div class="hide_box" onclick="dashangToggle()"></div>
<div class="shang_box">
    <a class="shang_close"  onclick="dashangToggle()">×</a>
    <div class="shang_tit">
        <p>Help us with donation</p>
    </div>
    <div class="shang_payimg">
        <div class="pay_img">
            <img src="/img/alipay.jpg" class="alipay" title="扫码支持">
            <img src="/img/weixin.jpg" class="weixin" title="扫码支持">
        </div>
    </div>
    <div class="shang_payselect">
        <span><label><input type="radio" name="pay" checked value="alipay">alipay</label></span><span><label><input type="radio" name="pay" value="weixin">weixin</label></span>
    </div>
</div>


</body>
<script src="/js/jquery.pjax.js?v=1.1.0" ></script>

<script src="/js/script.js?v=1.1.0" ></script>
<script>
    var img_resize = 'default';
    function initArticle() {
        /*渲染对应的表格样式*/
        
            $("#post .pjax table").addClass("green_title");
        

        /*渲染打赏样式*/
        
        $("input[name=pay]").on("click", function () {
            if($("input[name=pay]:checked").val()=="weixin"){
                $(".shang_box .shang_payimg .pay_img").addClass("weixin_img");
            } else {
                $(".shang_box .shang_payimg .pay_img").removeClass("weixin_img");
            }
        })
        

        /*高亮代码块行号*/
        

        /*访问数量*/
        
        $.getScript("//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js");
        

        /*代码高亮，行号对齐*/
        $('.pre-numbering').css('line-height',$('.has-numbering').css('line-height'));

        
        
    }

    /*打赏页面隐藏与展示*/
    
    function dashangToggle() {
        $(".shang_box").fadeToggle();
        $(".hide_box").fadeToggle();
    }
    

</script>

<!--加入行号的高亮代码块样式-->

<!--自定义样式设置-->
<style>
    
    
    .nav {
        width: 542px;
    }
    .nav.fullscreen {
        margin-left: -542px;
    }
    .nav-left {
        width: 120px;
    }
    
    
    @media screen and (max-width: 1468px) {
        .nav {
            width: 492px;
        }
        .nav.fullscreen {
            margin-left: -492px;
        }
        .nav-left {
            width: 100px;
        }
    }
    
    
    @media screen and (max-width: 1024px) {
        .nav {
            width: 492px;
            margin-left: -492px
        }
        .nav.fullscreen {
            margin-left: 0;
        }
    }
    
    @media screen and (max-width: 426px) {
        .nav {
            width: 100%;
        }
        .nav-left {
            width: 100%;
        }
    }
    
    
    .nav-right .title-list nav a .post-title, .nav-right .title-list #local-search-result a .post-title {
        color: #383636;
    }
    
    
    .nav-right .title-list nav a .post-date, .nav-right .title-list #local-search-result a .post-date {
        color: #5e5e5f;
    }
    
    
    .nav-right nav a.hover, #local-search-result a.hover{
        background-color: #e2e0e0;
    }
    
    

    /*列表样式*/
    

    /* 背景图样式 */
    
    


    /*引用块样式*/
    

    /*文章列表背景图*/
    

    
</style>







</html>
